#ifndef componente_H
#define componente_H
#include <iostream>
#include <vector>

using namespace std;

enum TipoComponente{ INTERRUPTOR, AND, OR, NOT };
enum Estado { V,F,D };
class ErrorInterruptorEntrada{};
class ErrorInterruptorSalida{};
class ErrorMultiplesEntradas{};
class ErrorSalida{};
class ErrorEntrada{};

class Componente {
      Estado salida;
      TipoComponente tipo;
      vector<Componente *> entrada;
      
      public:
             Componente();
             Componente(TipoComponente aTipo);             
             ~Componente();
             void operator =(Componente & comp){salida=comp.salida;tipo=comp.tipo;}
             bool operator ==(Componente &comp);
             bool operator !=(Componente &comp);
             TipoComponente verTipo(){return tipo;}             
             Estado verSalida(){return salida;}
             
             void conectarEntrada(Componente &componente);
             int numEntradasConectadas(){return entrada.size();}
             Componente * verEntradaConectada(int numEntrada);
             void salidaInterruptor(Estado aSalida);
             void reset();


};

  Componente::Componente(TipoComponente aTipo){
  tipo=aTipo;
  
  switch (aTipo){
    case INTERRUPTOR:
        salida=F;
        //entrada=NULL;
        break;
      case AND:
         // entrada=new Componente[2];
          salida=D;
          break;
      case OR:
        //  entrada=new Componente[2];
          salida=D;
          break;
      case NOT:
         // entrada=new Componente();
          salida=D;
          break;

    }
  }
/*bool Componente::operator !=(Componente &comp){
    bool result=true;
    if(salida!=comp.salida) result=false;
    else if(tipo!=comp.tipo)result=false;
    else if(entrada!=comp.entrada)result=false;
    return result;
}*/
    void   Componente::conectarEntrada(Componente &componente){
        int i,conectado;
        switch (tipo){
            case INTERRUPTOR:
                throw ErrorInterruptorEntrada();
                break;
              case AND:

                if(numEntradasConectadas()<2 ){
                  i=numEntradasConectadas()+1;
                  entrada[i]=&componente;
                     
                  }
                else throw ErrorMultiplesEntradas();
                  break;
              case OR:
                if(numEntradasConectadas()<2 ){
                  i=numEntradasConectadas()+1;
                  entrada[i]=&componente;
                  }
                else throw ErrorMultiplesEntradas();
                  break;
              case NOT:
                if(numEntradasConectadas()==0 ){
                  i=numEntradasConectadas()+1;
                  entrada[i]=&componente;
                  }
                else throw ErrorMultiplesEntradas();
                  break;

        }
    }

  void Componente::reset(){
      if(tipo!=INTERRUPTOR) salida =D;
      //entrada.clear();
  }

  Componente * Componente::verEntradaConectada(int numEntrada){
      if(numEntradasConectadas()<numEntrada)
          throw ErrorEntrada();
      return entrada[numEntrada];

  }
  void Componente::salidaInterruptor(Estado aSalida){
      if(tipo==INTERRUPTOR){
          if(aSalida!=D)
               salida=aSalida;
          else throw ErrorInterruptorSalida();
      }
  }
#endif
